﻿using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using wepoverkefni5.Models;
using System.Net;
using System.Web.Mvc;
using System.IO;
using System;
using System.Web;
using System.Diagnostics;

namespace wepoverkefni5.Controllers
{
    /// <summary>
    /// API Controller for handling all music CRUD operations
    /// </summary>
    public class MusicController : ApiController
    {
        DataRepository m_rep = new DataRepository();

        /// <summary>
        /// GET /api/music/5 - get
        /// Get a song by id
        /// </summary>
        /// <param name="id">Represents the id of the song requested</param>
        /// <returns>Song object containing all attr for a song</returns>
        public Song Get(int id)
        {
            var result = m_rep.GetSongById(id);
            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return result;
        }

        /// <summary>
        /// GET /api/music/(search string) - get
        /// Get all songs containing a search string specified by the user
        /// </summary>
        /// <param name="search">Represents the search criteria/filter</param>
        /// <returns>Collection of song´s objects</returns>
        public IQueryable<Song> Get(string search)
        {
            var result = m_rep.GetSongBySearch(search);
            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return result;
        }

        /// <summary>
        /// GET /api/music
        /// Gett all songs
        /// </summary>
        /// <returns>Collection of song´s objects</returns>
        public IQueryable<Song> GetAllMusic()
        {
            var result = m_rep.GetAllSongs();
            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return result;
        }

        /// <summary>
        /// Upload mp3 music file through ajax from client
        /// </summary>
        /// <returns>HttpResponseMessage response</returns>
        public HttpResponseMessage PostUploadSong()
        {
            //System.Diagnostics.Debug.WriteLine("Trying to add song to database!");
            if (!Request.Content.IsMimeMultipartContent("form-data"))
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }
            string serverPath = HttpContext.Current.Server.MapPath("~");
            var files = HttpContext.Current.Request.Files;
            try
            {
                foreach (var item in files.AllKeys)
                {
                    //Add song to database
                    Song result = new Song();
                    result.songName = "songName";
                    result.songArtist = "songArtist";
                    result.songAlbum = "songAlbum";
                    result.songGenre = "songGenre";
                    result.songSource = "songSource";
                    result.songLength = "4:44";
                    m_rep.addSong(result);

                    string songsPath = serverPath + "\\Content\\Songs\\" + result.Id + ".mp3";
                    files[item].SaveAs(songsPath);
                    //files[item].InputStream.Dispose();
                    //files[item].InputStream.Close();

                    TagLib.File tagFile = TagLib.File.Create(songsPath);
                    var duration = tagFile.Properties.Duration.Minutes + ":" + tagFile.Properties.Duration.Seconds;

                    //System.Diagnostics.Debug.WriteLine("Track info: " + duration + " - " + tagFile.Tag.TrackCount);
                    //System.Diagnostics.Debug.WriteLine("Title: " + tagFile.Tag.Title + ", " + tagFile.Tag.FirstPerformer + ", " + tagFile.Tag.Album);
                    m_rep.updateSongSource(result.Id, "../../Content/Songs/" + result.Id + ".mp3", tagFile.Tag.Title, tagFile.Tag.Album, tagFile.Tag.FirstPerformer, tagFile.Tag.FirstGenre, duration);
                    //tagFile.Dispose();
                }
                //HttpContext.Current.Request.InputStream.Close();
                //HttpContext.Current.Request.InputStream.Dispose();
            }
            catch (IOException)
            {
                throw new HttpResponseException("A generic error occured. Please try again later.", HttpStatusCode.InternalServerError);
            }

            HttpResponseMessage response = new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.Created;
            return response;
        }

        /// <summary>
        /// DELETE /api/music/5 - delete
        /// Delete song
        /// </summary>
        /// <param name="id">Represents the id of the song to be deleted</param>
        /// <returns>HttpResponseMessage response</returns>
        public HttpResponseMessage DeleteSong(int id)
        {
            //System.Diagnostics.Debug.WriteLine("Trying to remove song with id" + id);
            var tobeDeleted = m_rep.GetSongById(id);
            if (tobeDeleted == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            String serverPath = HttpContext.Current.Server.MapPath("~");
            String musicPath = serverPath + "\\Content\\Songs\\";
            String songPath = musicPath + tobeDeleted.Id + ".mp3";
            try
            {
                //var tempFile = System.IO.Path.GetTempFileName();
                //System.IO.File.Copy(songPath, tempFile, true);
                //System.IO.File.Delete(tempFile);
                System.IO.File.Delete(songPath);                
            }
            catch (IOException)
            {
                //TODO IOException: The process cannot access the file 'filename' because it is being used by another pr...
                
                //throw new HttpResponseException("A generic error occured. Please try again later.", HttpStatusCode.InternalServerError);
            }
            m_rep.DeleteSong(tobeDeleted);
            HttpResponseMessage response = new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.OK;
            return response;
        }
    }
}
